import { Link, CodeBlockTransformer } from '@brillout/docpress'

**Environment**: server.

`getContext()` enables telefunctions to access contextual information.

```ts
// TodoList.telefunc.ts
// Environment: server

import { getContext } from 'telefunc'

export async function onLoad() {
  const context = getContext()
  const { user } = context
  const todoItems = await Todo.findMany({ select: 'text', authorId: user.id })
  return {
    todoItems,
    userName: user.name
  }
}
```

It's most commonly used for implementing permissions, see <Link href="/permissions" />.


## Provide

Before we can use `getContext()`, we need to provide the `context` object to <Link text="Telefunc's Server Middleware" href="/telefunc" />:

```ts
// server.ts

// Server (Express.js/Fastify/...)

import { telefunc } from 'telefunc'

// Telefunc middleware
app.all('/_telefunc', async (req: Request, res: Response) => {
  // Authentication middlewares (e.g. Passport.js or Grant) usually provide information
  // about the logged-in user on the `req` object:
  const user = req.user
  // Or when using a third-party authentication provider (e.g. Auth0):
  // @detype-uncomment const user = await authProviderApi.getUser(req.headers)

  const httpResponse = await telefunc({
    // We provide the context object here:
    context: {
      user
    },
    url: req.url,
    method: req.method,
    body: req.body
  })

  const { body, statusCode, contentType } = httpResponse
  res.status(statusCode).type(contentType).send(body)
})
```


## Access

If you get this error:

<CodeBlockTransformer lineBreak="break-word">
```
[telefunc][Wrong Usage][getContext()] Cannot access context object, see https://telefunc.com/getContext#access
```
</CodeBlockTransformer>

Then this means that `getContext()` was called after an `await` operator:

```ts
// TodoList.telefunc.ts

export async function myTelefunction() {
  await something()
  // ❌ Bad: we should call getContext() before `await something()`
  const context = getContext()
}
```

Make sure to call `getContext()` before any `await` operators:

```ts
// TodoList.telefunc.ts

export async function myTelefunction() {
  // ✅ Good: we call getContext() before `await`
  const context = getContext()
  await something()
}
```


## TypeScript

We can use `Telefunc.Context` to globally set the type of `const context = getContext()`:

```ts ts-only
// TelefuncContext.d.ts

import 'telefunc'
import type { User } from './User.ts'

declare module 'telefunc' {
  namespace Telefunc {
    interface Context {
      user: null | User
    }
  }
}
```
```ts ts-only
// User.ts

export type User = { id: number }
```
```ts ts-only
// *.telefunc.ts

import { getContext } from 'telefunc'

export async function someTelefunction() {
  // TypeScript knows that `user.id` is a `number`
  const { user } = getContext()
}
```

We can also directly set `const context = getContext<MyContext>()`:

```ts ts-only
// *.telefunc.ts

import { getContext } from 'telefunc'

type Context = {
  userId: number
}

export async function someTelefunction() {
  // TypeScript knows that `userId` is a `number`
  const { userId } = getContext<Context>()
}
```
